namespace Core
{
    using System;
    using Base;
    using Contracts.Enums;
    using Contracts.Interfaces;

    /// <summary>
    /// Robot slot class
    /// </summary>
    public sealed class Slot : PropertyChangedBase, ISlot
    {
        private SlotGroupsEnum _group;
        private SlotTypesEnum _fittable;
        private SizesEnum _sizes;
        private IModule _module;
        private readonly ushort _sortOrder;

        /// <summary>
        /// Initializes a new instance of the <see cref="T:Core.Slot"/> class.
        /// </summary>
        public Slot(ushort sortOrder, SlotGroupsEnum group, SlotTypesEnum fittable, SizesEnum sizes)
        {
            _group = group;
            _fittable = fittable;
            _sizes = sizes;
            _sortOrder = sortOrder;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Core.Slot"/> class.
        /// </summary>
        public Slot( SlotGroupsEnum group, SlotTypesEnum fittable)
            : this(0, group, fittable, SizesEnum.NotDefined)
        {
        }

        /// <summary>
        /// Obtains the sorting order
        /// </summary>
        public ushort SortOrder
        {
            get { return _sortOrder; }
        }

        /// <summary>
        /// Obtains or defines the slot type
        /// </summary>
        public SlotGroupsEnum SlotGroup
        {
            get { return _group; }
            set { _group = value; }
        }
        /// <summary>
        /// Obtains or defines the slot type
        /// </summary>
        public SlotTypesEnum Fittable
        {
            get { return _fittable; }
            set { _fittable = value; }
        }
        /// <summary>
        /// Obtains or defines the slot type
        /// </summary>
        public SizesEnum Sizes
        {
            get { return _sizes; }
            set { _sizes = value; }
        }

        /// <summary>
        /// Obtains or defines the fitted module
        /// </summary>
        public IModule FittedModule
        {
            get { return _module; }
            set
            {
                _module = value; 
                NotifyPropertyChange(() => FittedModule);
                NotifyPropertyChange(() => HasModule);
                NotifyPropertyChange(() => CanActivate);
            }
        }

        /// <summary>
        /// Determines if the slot is occupied
        /// </summary>
        public bool HasModule
        {
            get { return _module != null; }
        }
        /// <summary>
        /// Determines if the fitted module can be activated
        /// </summary>
        public bool CanActivate
        {
            get { return HasModule && FittedModule.ActivationType == ModuleActivationTypesEnum.Active; }
        }
    }
}